package br.com.jk.consultaxml.gerenciar;

import br.com.jk.cotacao.*;
import br.com.jk.cliente.Cliente;
import br.com.jk.cliente.ClienteDao;
import br.com.jk.empresa.Empresa;
import br.com.jk.empresa.EmpresaDao;
import br.com.jk.util.pesquisa.Pesquisa.Opcao;
import java.util.List;
import org.hibernate.Criteria;
import org.hibernate.FetchMode;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.hibernate.criterion.MatchMode;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Restrictions;

/**
 *
 * @author camilo
 */
public class GerenciaXmlDaoHibernate implements GerenciaXmlDao {

  private Session session;
  private Transaction transacao;

  public void setSession(Session session) {
    this.session = session;
  }

  @Override
  public void salvar(GerenciaXml forn) {
    this.transacao = this.session.beginTransaction();
    this.session.saveOrUpdate(forn);
    this.transacao.commit();
    this.session.close();
  }

  @Override
  public void excluir(GerenciaXml forn) {
    this.transacao = this.session.beginTransaction();
    this.session.delete(forn);
    this.transacao.commit();
    this.session.close();
  }

  @Override
  public GerenciaXml carregar(int id) {
    return (GerenciaXml) this.session.get(GerenciaXml.class, id);
  }

  @Override
  public GerenciaXml carregarCodEan(String cod) {
    Criteria criteria = this.session.createCriteria(GerenciaXml.class);
    criteria.add(Restrictions.naturalId().set(GerenciaXml.ATTRIBUTE_COD_COTACAO, cod));
    return (GerenciaXml) criteria.uniqueResult();
  }

  @Override
  public List<GerenciaXml> listar() {
    return this.session.createCriteria(GerenciaXml.class)
            .addOrder(Order.asc(GerenciaXml.ATTRIBUTE_DESCRICAO)).list();
  }

  /**
   * Retorna um objeto criteria com o "Restriction" de acordo a necessidade do usuário <br
   * />
   * <br />
   * Os parâmetros <i>strCrit </i>e<i> dateCrit</i> podem ser declarados como <b>null</b>
   * e o parâmetro <i>intCrit </i> pode ser declarado 0, mas ao menos um dos três precisa
   * ter um valor válido especificado.<br />
   * <br />
   * Caso não seja definida uma opção a opção padrão é <i>CONTENDO</i>
   * e o critério usado será o <i>strCrit</i>
   *
   * @param property Nome do atributo mapeado
   * @param opcao Tipo da pesquisa (contendo, igual, maior, etc)
   * @param strCrit Caso não possua defina null
   * @param intCrit Caso não possua defina 0
   * @param dateCrit Caso não possua defina null
   *
   * @return Criteria
   */
  private Criteria getCriteriaOpcao(String property, Opcao opcao, String strCrit, int intCrit) {
    Criteria criteria = this.session.createCriteria(GerenciaXml.class);
    switch (opcao) {
      case CONTENDO:
        criteria.add(Restrictions.ilike(property, strCrit, MatchMode.ANYWHERE));
        break;
      case DIFERENTE:
        if (strCrit == null && intCrit > -1) {
          criteria.add(Restrictions.ne(property, intCrit));
        } else {
          criteria.add(Restrictions.ne(property, strCrit));
        }
        break;
      case IGUAL:
        if (strCrit == null && intCrit > -1) {
          criteria.add(Restrictions.eq(property, intCrit));
        } else {
          criteria.add(Restrictions.eq(property, strCrit));
        }
        break;
      case INICIA:
        criteria.add(Restrictions.ilike(property, strCrit, MatchMode.START));
        break;
      case MAIOR:
        criteria.add(Restrictions.ge(property, intCrit));
        break;
      case MENOR:
        criteria.add(Restrictions.le(property, intCrit));
        break;
      case TERMINA:
        criteria.add(Restrictions.ilike(property, strCrit, MatchMode.END));
        break;
    }
    return criteria;
  }

  @Override
  public List<GerenciaXml> pesquisaPadrao(String property, String criterio, Opcao opcao) {
    Criteria criteria = getCriteriaOpcao(property, opcao, criterio, 0);
    criteria.addOrder(Order.asc(property));
    return criteria.list();
  }

  @Override
  public List<GerenciaXml> pesquisaPadrao(String property, int criterio, Opcao opcao) {
    Criteria criteria = getCriteriaOpcao(property, opcao, null, criterio);
    criteria.addOrder(Order.asc(property));
    return criteria.list();
  }

  @Override
  public List<GerenciaXml> listar(Empresa empresa, Cliente cliente) {
    Criteria criteria = this.session.createCriteria(GerenciaXml.class);
    criteria.setFetchMode(EmpresaDao.NAME_TABLE, FetchMode.JOIN)
            .add(Restrictions.eq(GerenciaXml.ATTRIBUTE_EMPRESA, empresa));
    criteria.setFetchMode(ClienteDao.NAME_TABLE, FetchMode.JOIN)
            .add(Restrictions.eq(GerenciaXml.ATTRIBUTE_CLIENTE, cliente));
    return criteria.list();
  }
}
